import { ItemData } from "../Base/BaseTemplateClass"
import { BaseCsv } from "../Excel/BaseCsv"

export class Utils {

    public static valueToString(type: string, data: any): string {
        switch (type) {
            case "string":
                return data
            case "string[]":
                return data.join(",")
            case "number":
            case "int":
            case "float":
            case "long":
                return data + ''
            case "number[]":
            case "int[]":
            case "float[]":
            case "long[]":
                return data.join(",")
            case "number[][]":
            case "int[][]":
            case "float[][]":
            case "long[][]":
                let n: string[] = []
                for (let i = 0; i < data.length; i++) {
                    n.push(data[i].join(","))
                }
                return n.join(";")
            case "cc.Vec2":
                return data.x + "," + data.y
            case "cc.Vec2[]":
                let vn: string[] = []
                for (let i = 0; i < data.length; i++) {
                    vn.push(data[i].x + "," + data[i].y)
                }
                return vn.join(";")
            case "cc.Color":
                return data.toHEX("#rrggbb")
            case "cc.Color[]":
                let cn: string[] = []
                for (let i = 0; i < data.length; i++) {
                    cn.push(data[i].toHEX("#rrggbb"))
                }
                return cn.join(",")
            case "ItemData":
                return (data as ItemData).toString()
            case "ItemData[]":
                let sn: string[] = []
                for (let i = 0; i < data.length; i++) {
                    sn.push((data[i] as ItemData).toString())
                }
                return sn.join(";")
            case "boolean":
                let s = data ? 1 : 0
                return s + ''
            case "boolean[]":
                let bn: number[] = []
                for (let i = 0; i < data.length; i++) {
                    bn.push(data[i] ? 1 : 0)
                }
                return bn.join(",")
            default:
                return data
        }
    }

    public static stringToValue(data: string, type: string) {
        switch (type) {
            case "string":
                return data
            case "string[]":
                return data.split(",")
            case "number":
            case "int":
            case "float":
            case "long":
                return data == "" ? 0 : Number(data)
            case "number[]":
            case "int[]":
            case "float[]":
            case "long[]":
                return Utils.stringToNumberArr(data)
            case "number[][]":
            case "int[][]":
            case "float[][]":
            case "long[][]":
                return Utils.stringToNumberArrArr(data)
            case "cc.Vec2":
                return Utils.stringToVec(data)
            case "cc.Vec2[]":
                return Utils.stringToVecArr(data)
            case "cc.Color":
                return Utils.stringToColor(data)
            case "cc.Color[]":
                return Utils.stringToColorArr(data)
            case "ItemData":
                return Utils.stringToItem(data)
            case "ItemData[]":
                return Utils.stringToItemArr(data)
            case "boolean":
                return Utils.stringToBoolean(data)
            case "boolean[]":
                return Utils.stringTpBooleanArr(data)
            default:
                return data
        }
    }

    private static stringToNumberArr(s: string): number[] {
        let arr: number[] = []
        if (s.length > 0) {
            let as = s.split(",")
            for (let i = 0; i < as.length; i++) {
                as[i].length && arr.push(Number(as[i]))
            }
        }
        return arr
    }

    private static stringToNumberArrArr(s: string): number[][] {
        let arr: number[][] = []
        if (s.length > 0) {
            let as = s.split(";")
            for (let i = 0; i < as.length; i++) {
                as[i].length && arr.push(Utils.stringToNumberArr(as[i]))
            }
        }
        return arr
    }

    private static stringToVec(s: string): cc.Vec2 {
        let n = Utils.stringToNumberArr(s)
        if (n.length >= 2)
            return cc.v2(n[0], n[1])
        return cc.v2(0, 0)
    }

    private static stringToVecArr(s: string): cc.Vec2[] {
        let v: cc.Vec2[] = []
        if (s.length > 0) {
            let n = s.split(";")
            for (let i = 0; i < n.length; i++) {
                n[i].length > 0 && v.push(Utils.stringToVec(n[i]))
            }
        }
        return v
    }

    private static stringToColor(s: string): cc.Color {
        if (s.length >= 6) {
            let s1: string = "0x" + s.substring(0, 2)
            let s2: string = "0x" + s.substring(2, 4)
            let s3: string = "0x" + s.substring(4, 6)
            let s4: string = ""
            if (s.length > 6) {
                s4 = "0x" + s.substring(6, 8)
            }
            let r = parseInt(s1)
            let g = parseInt(s2)
            let b = parseInt(s3)
            let a = s4 == "" ? 255 : parseInt(s4)
            let c: cc.Color = new cc.Color(r, g, b, a)
            return c
        }
        return cc.Color.BLACK
    }

    private static stringToColorArr(s: string): cc.Color[] {
        let cs: cc.Color[] = []
        if (s.length > 0) {
            let ar = s.split(",")
            for (let i = 0; i < ar.length; i++) {
                ar[i].length > 0 && cs.push(Utils.stringToColor(ar[i]))
            }
        }
        return cs
    }

    private static stringToItem(s: string): ItemData {
        let arr = Utils.stringToNumberArr(s)
        if (arr.length >= 3) {
            return new ItemData(arr[0], arr[1], arr[2])
        }
        return null
    }

    private static stringToItemArr(s: string): ItemData[] {
        let v: ItemData[] = []
        if (s.length > 0) {
            let n = s.split(";")
            for (let i = 0; i < n.length; i++) {
                if (n[i].length > 0) {
                    let item = Utils.stringToItem(n[i])
                    if (item) {
                        v.push(item)
                    }
                }
            }
        }
        return v
    }

    private static stringToBoolean(s: string): boolean {
        return !(s == "" || s == "0" || s.toLowerCase() == "false")
    }

    private static stringTpBooleanArr(s: string): boolean[] {
        let r: boolean[] = []
        if (s.length > 0) {
            let ar = s.split(",")
            for (let i = 0; i < ar.length; i++) {
                ar[i].length > 0 && r.push(Utils.stringToBoolean(ar[i]))
            }
        }
        return r
    }

    public static convert<T extends BaseCsv, T1>(asset: T1, t: { new(): T }): Map<number, T> {
        if (asset instanceof cc.JsonAsset) {
            let rows: string[] = asset.json.rows
            let headers = asset.json.header
            let m: Map<number, T> = new Map()
            for (let key in rows) {
                let c: T = new t
                Utils.jsonToValue<T>(rows[key], headers, c)
                let id = parseInt(key)
                if (id)
                    m.set(id, c)
            }
            return m
        }
    }

    public static jsonToValue<T extends BaseCsv>(data: any, header: string[], t: T) {
        for (let index in header) {
            let val = data[index] || ""
            t[header[index]] = Utils.stringToValue(val, t.typeStr[header[index]])
        }
    }

    public static getCamera() {
        let cvs = cc.find('Canvas')
        return cvs.getChildByName("Main Camera")
    }

    /**
     * 随机数 [min,max]
     * @param min 
     * @param max 
     * @returns 
     */
    public static rand(min, max) {
        return parseInt(Math.random() * (max - min + 1) + min);
    }

}